﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows.Browser;
using GSSoftSL.Utility;
using GSSoftSL.Web;
using GSSoftSL.Web.Models;
using GSSoftSL.Web.Models.Shared;
using GSSoftSL.Web.Services;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;

namespace GSSoftSL.ViewModel.HocVienVM
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class HocVienHocPhiViewModel : ViewModelBase
    {
        private GSSoftContext _dc;
        public GSSoftContext DC
        {
            get { return _dc; }
            set { _dc = value; }
        }

        private HocVienMainViewModel _mainVM;
        public HocVienMainViewModel MainViewModel
        {
            get { return _mainVM; }
            set { _mainVM = value; }
        }

        
        public bool IsBusy
        {
            get { return MainViewModel.IsBusy; }
            set { MainViewModel.IsBusy = value; }
        }

        /// <summary>
        /// Initializes a new instance of the HocVienDongHocPhiViewModel class.
        /// </summary>
        public HocVienHocPhiViewModel()
        {
            KhoaHocHocPhi.CallBack = CalculateBienLai;
            _dc = ServiceLocator.Current.GetInstance<DomainContext>("HocVien") as GSSoftContext;
            _mainVM = ServiceLocator.Current.GetInstance<HocVienMainViewModel>("HocVien");
            BienLai = new BienLai();
            IsBusy = true;
            _dc.Load(_dc.GetMonsQuery().OrderBy(n => n.ThuTu), LoadBehavior.RefreshCurrent, LoadMon_Completed, null);
        }

        private void LoadMon_Completed(LoadOperation<Mon> load)
        {
            var lstMons = load.Entities.ToList();
            lstMons.Insert(0, new Mon(){MaMon = "-1", TenMon = "- Chọn môn -"});
            Mons = lstMons;
            IsBusy = false;
        }
        
        public const string MonsPropertyName = "Mons";
        private List<Mon> _mons = null;
        public List<Mon> Mons
        {
            get
            {
                return _mons;
            }
            set
            {
                if (_mons == value)
                {
                    return;
                }

                RaisePropertyChanging(MonsPropertyName);
                _mons = value;
                RaisePropertyChanged(MonsPropertyName);
                if (_mons != null && _mons.Count > 0)
                    Mon = _mons[0];
                else
                {
                    Mon = null;
                }
            }
        }
        
        public const string MonPropertyName = "Mon";
        private Mon _mon = null;
        public Mon Mon
        {
            get
            {
                return _mon;
            }
            set
            {
                if (_mon == value)
                {
                    return;
                }

                RaisePropertyChanging(MonPropertyName);
                _mon = value;
                RaisePropertyChanged(MonPropertyName);
                if (_mon != null && _mon.MaMon != "-1")
                {
                    IsBusy = true;
                    _dc.Load(_dc.GetLopsWithKhoaHocsQuery().Where(n => n.MaMon == _mon.MaMon).OrderBy(n => n.MaLop),
                             LoadBehavior.RefreshCurrent, LoadLop_Completed, null);
                }
                else
                {
                    Lops = null;
                }
            }
        }

        private void LoadLop_Completed(LoadOperation<Lop> load)
        {
            var lstLops = load.Entities.ToList();
            lstLops.Insert(0, new Lop(){MaLop = "-1", TenLop = "- Chọn lớp -"});
            Lops = lstLops;
        }
        
        public const string LopsPropertyName = "Lops";
        private List<Lop> _lops = null;
        public List<Lop> Lops
        {
            get
            {
                return _lops;
            }
            set
            {
                if (_lops == value)
                {
                    return;
                }

                RaisePropertyChanging(LopsPropertyName);
                _lops = value;
                RaisePropertyChanged(LopsPropertyName);
                if (_lops != null && _lops.Count > 0)
                {
                    Lop = _lops[0];
                }
                else
                {
                    Lop = null;
                }
            }
        }
        
        public const string LopPropertyName = "Lop";
        private Lop _lop = null;
        public Lop Lop
        {
            get
            {
                return _lop;
            }
            set
            {
                if (_lop == value)
                {
                    return;
                }

                RaisePropertyChanging(LopPropertyName);
                _lop = value;
                RaisePropertyChanged(LopPropertyName);
                if (_lop != null && _lop.MaLop != "-1")
                {
                    LoadCommand.Execute(null);
                }
                else
                {
                    KhoaHocHocPhis = null;
                }
            }
        }
        
        private HocVien _hocVien = null;
        public HocVien HocVien
        {
            get
            {
                return _hocVien;
            }
            set
            {
                if (_hocVien == value)
                {
                    return;
                }
                _hocVien = value;
                RaisePropertyChanged("HocVien");
                //_dc.Load<KhoaHocHocPhi>(_dc.GetKhoaHocsDaDongHocPhiQuery(_hocVien.MaHV), LoadBehavior.RefreshCurrent, LoadKhoaHocsDaDongHocPhi_Completed, null);
                BienLai = new BienLai();
                _bienLai.MaHV = _hocVien.MaHV;
                KhoaHocHocPhis = null;
                KhoaHocHocPhiChons = null;
                _listKhoaHocsHVDangTheoHoc = null;
                LoadCommand.Execute(null);
                if (_hocVien != null)
                {
                    IsBusy = true;
                    _dc.Load(_dc.GetKhoaHocHocViensQuery().Where(n => n.MaHV == _hocVien.MaHV),
                             LoadBehavior.RefreshCurrent, LoadKhoaHocHocVien_Completed, null);
                }
            }
        }

        private void LoadKhoaHocHocVien_Completed(LoadOperation<KhoaHocHocVien> load)
        {
            _listKhoaHocsHVDangTheoHoc = load.Entities.ToList();
            IsBusy = false;
        }

        private List<KhoaHocHocVien> _listKhoaHocsHVDangTheoHoc = null;

        private void LoadKhoaHocsDaDongHocPhi_Completed(LoadOperation<KhoaHocHocPhi> load)
        {
            KhoaHocHocPhis = new ObservableCollection<KhoaHocHocPhi>(load.Entities.ToArray());
            IsBusy = false;
        }

        private ObservableCollection<KhoaHocHocPhi> _khoaHocHocPhis = null;
        public ObservableCollection<KhoaHocHocPhi> KhoaHocHocPhis
        {
            get
            {
                return _khoaHocHocPhis;
            }
            set
            {
                if (_khoaHocHocPhis == value)
                {
                    return;
                }
                _khoaHocHocPhis = value;
                RaisePropertyChanged("KhoaHocHocPhis");
            }
        }

        
        private BienLai _bienLai = null;
        public BienLai BienLai
        {
            get
            {
                return _bienLai;
            }
            set
            {
                if (_bienLai == value)
                {
                    return;
                }
                _bienLai = value;
                if (_bienLai.EntityState == EntityState.New || _bienLai.EntityState == EntityState.Detached)
                    _bienLai.NgayDong = DateTime.Now.Date;
                RaisePropertyChanged("BienLai");
            }
        }


        private KhoaHocHocPhi _currentKhoaHocHocPhi = null;
        public KhoaHocHocPhi CurrentKhoaHocHocPhi
        {
            get
            {
                return _currentKhoaHocHocPhi;
            }
            set
            {
                if (_currentKhoaHocHocPhi == value)
                {
                    return;
                }
                _currentKhoaHocHocPhi = value;
                RaisePropertyChanged("CurrentKhoaHocHocPhi");
            }
        }

        private ObservableCollection<KhoaHocHocPhi> _khoaHocHocPhiChons = null;
        public ObservableCollection<KhoaHocHocPhi> KhoaHocHocPhiChons
        {
            get
            {
                return _khoaHocHocPhiChons;
            }
            set
            {
                if (_khoaHocHocPhiChons == value)
                {
                    return;
                }
                _khoaHocHocPhiChons = value;
                RaisePropertyChanged("KhoaHocHocPhiChons");
            }
        }

        private KhoaHocHocPhi _currentKhoaHocHocPhiChon = null;
        public KhoaHocHocPhi CurrentKhoaHocHocPhiChon
        {
            get
            {
                return _currentKhoaHocHocPhiChon;
            }
            set
            {
                if (_currentKhoaHocHocPhiChon == value)
                {
                    return;
                }
                _currentKhoaHocHocPhiChon = value;
                RaisePropertyChanged("CurrentKhoaHocHocPhiChon");
            }
        }

        
        private bool _isEnabled = false;
        public bool IsEnabled
        {
            get
            {
                return _isEnabled;
            }
            set
            {
                if (_isEnabled == value)
                {
                    return;
                }
                _isEnabled = value;
                RaisePropertyChanged("IsEnabled");
            }
        }

        private RelayCommand _addBienLaiCTCommand;
        public RelayCommand AddBienLaiCTCommand
        {
            get
            {
                return _addBienLaiCTCommand
                       ?? (_addBienLaiCTCommand = new RelayCommand(
                                                      () =>
                                                      {
                                                          if (_currentKhoaHocHocPhi == null || _bienLai == null || (EnumTrangThaiHocPhi)_currentKhoaHocHocPhi.TrangThaiHocPhi == EnumTrangThaiHocPhi.HoanTat)
                                                              return;
                                                          if (_khoaHocHocPhiChons.Count(n => n.KhoaHocId == _currentKhoaHocHocPhi.KhoaHocId) > 0)
                                                              return;
                                                          var tmpCT = _currentKhoaHocHocPhi.CreateCopy();
                                                          if ((EnumTrangThaiHocPhi)tmpCT.TrangThaiHocPhi == EnumTrangThaiHocPhi.ChuaDong)
                                                              tmpCT.TrangThaiHocPhi = (int)EnumTrangThaiHocPhi.HoanTat;
                                                          KhoaHocHocPhiChons.Add(tmpCT);
                                                          this.CalculateBienLai();
                                                      }));
            }
        }

        private RelayCommand _removeBienLaiCTCommand;

        /// <summary>
        /// Gets the RemoveBienLaiCTCommand.
        /// </summary>
        public RelayCommand RemoveBienLaiCTCommand
        {
            get
            {
                return _removeBienLaiCTCommand
                    ?? (_removeBienLaiCTCommand = new RelayCommand(
                                          () =>
                                          {
                                              if (_bienLai == null || _currentKhoaHocHocPhiChon == null)
                                                  return;
                                              if (KhoaHocHocPhiChons.Where(n => n.KhoaHocId == _currentKhoaHocHocPhiChon.KhoaHocId).Count() < 1)
                                                  return;
                                              KhoaHocHocPhiChons.Remove(_currentKhoaHocHocPhiChon);
                                              this.CalculateBienLai();
                                          }));
            }
        }

        private RelayCommand _saveCommand;
        /// <summary>
        /// Gets the SaveCommand.
        /// </summary>
        public RelayCommand SaveCommand
        {
            get
            {
                return _saveCommand
                       ?? (_saveCommand = new RelayCommand(
                                              () =>
                                              {
                                                  if (_hocVien == null || _bienLai == null || KhoaHocHocPhiChons.Count <= 0 || _dc.IsSubmitting)
                                                      return;
                                                  ConfirmWindow.CreateNew("Bạn có muốn lưu?", Save);
                                              }));
            }
        }

        private void Save()
        {
            _bienLai.BienLaiId = Guid.NewGuid();
            _bienLai.SoBienLai = "";
            _bienLai.GhiChu = _bienLai.GhiChu ?? "";
            _bienLai.MaHV = _hocVien.MaHV;
            _bienLai.NguoiThu = UtilityFunction.GetCurrentUserId();
            _dc.BienLais.Add(_bienLai);
            BienLaiCT ct;
            KhoaHocHocVien khhv;
            //KhoaHoc kh;
            foreach (var item in KhoaHocHocPhiChons)
            {
                ct = new BienLaiCT()
                {
                    KhoaHocId = item.KhoaHocId,
                    HocPhiTruocGiam = item.HocPhiTheoTrangThai,
                    HocPhiSauGiam = item.HocPhiSauGiam,
                    MucGiam = item.MucGiam
                };
                //kh = _lop.KhoaHocs.Single(n => n.KhoaHocId == item.KhoaHocId);
                if (_listKhoaHocsHVDangTheoHoc.Count(n => n.KhoaHocId == item.KhoaHocId) > 0)
                {
                    khhv = _listKhoaHocsHVDangTheoHoc.Single(n => n.KhoaHocId == item.KhoaHocId);
                    if ((EnumTrangThaiHocPhi)khhv.TrangThaiHocPhi == EnumTrangThaiHocPhi.ChuaDong)
                        khhv.TrangThaiHocPhi = (int)item.TrangThaiHocPhi;
                    else
                        khhv.TrangThaiHocPhi = (int) EnumTrangThaiHocPhi.HoanTat;
                    //khhv.KhoaHoc = kh;
                }
                else
                {
                    khhv = new KhoaHocHocVien()
                               {
                                   KhoaHocId = item.KhoaHocId,
                                   MaHV = _hocVien.MaHV,
                                   TrangThai = 0,
                                   TrangThaiHocPhi = (int)item.TrangThaiHocPhi
                               };
                    //kh.KhoaHocHocViens.Add(khhv);
                    _dc.KhoaHocHocViens.Add(khhv);
                    _listKhoaHocsHVDangTheoHoc.Add(khhv);
                }
                _bienLai.BienLaiCTs.Add(ct);
            }

            IsBusy = true;
            _dc.SubmitChanges(SubmitChanges_Completed, null);
        }

        private void SubmitChanges_Completed(SubmitOperation so)
        {
            IsBusy = false;
            IsEnabled = true;
            KhoaHocHocPhiChons = new ObservableCollection<KhoaHocHocPhi>();
            //_dc.Load<KhoaHocHocPhi>(_dc.GetKhoaHocsDaDongHocPhiQuery(_hocVien.MaHV), LoadBehavior.RefreshCurrent, LoadKhoaHocsDaDongHocPhi_Completed, null);
            string baseUrl = UtilityFunction.GetBaseAddress() + "type=0&id=" + _bienLai.BienLaiId;
            UtilityFunction.ShowReportDialog(baseUrl, 800, 550);
            LoadCommand.Execute(null);
        }

        private RelayCommand _newBienLaiCommand;
        /// <summary>
        /// Gets the NewBienLaiCommand.
        /// </summary>
        public RelayCommand NewBienLaiCommand
        {
            get
            {
                return _newBienLaiCommand
                       ?? (_newBienLaiCommand = new RelayCommand(
                                                    () =>
                                                        {
                                                            IsEnabled = true;
                                                            if (_dc.HasChanges)
                                                                _dc.RejectChanges();
                                                            BienLai = new BienLai();
                                                            KhoaHocHocPhiChons = new ObservableCollection<KhoaHocHocPhi>();
                                                        }));
            }
        }

        private RelayCommand _loadCommand;
        /// <summary>
        /// Load danh sách khóa học, có thông tin về trạng thái đóng học phí
        /// </summary>
        public RelayCommand LoadCommand
        {
            get
            {
                return _loadCommand
                    ?? (_loadCommand = new RelayCommand(
                                          () =>
                                          {
                                              if (HocVien == null || _lop == null || _lop.MaLop == "-1")
                                              {
                                                  
                                              }
                                              else
                                              {
                                                  IsBusy = true;
                                                  _dc.Load<KhoaHocHocPhi>(_dc.GetKhoaHocsDaDongHocPhiQuery(_hocVien.MaHV, _lop.LopId), LoadBehavior.RefreshCurrent, LoadKhoaHocsDaDongHocPhi_Completed, null);
                                                  BienLai = new BienLai();
                                              }
                                          }));
            }
        }

        public void CalculateBienLai()
        {
            _bienLai.TongTienTruocGiam = KhoaHocHocPhiChons.Sum(n => n.HocPhiTheoTrangThai);
            _bienLai.TongTienThanhToan = _bienLai.TongTienSauGiam = KhoaHocHocPhiChons.Sum(n => n.HocPhiSauGiam);
            /*_bienLai.TongTienTruocGiam = KhoaHocHocPhiChons.Sum(n => n.HocPhiDeNghi);
            _bienLai.TongTienThanhToan = _bienLai.TongTienSauGiam = KhoaHocHocPhiChons.Sum(n => n.HocPhiSauGiam);*/
        }
    }
}